package ex2.employee;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.Iterator;

public class CReportInputReader {
	
	
	private static final String ILLEGAL_EXPENSE_AMOUNT_ENTER_AGAIN = "Illegal expense amount. Enter again";
	private static final String ILLEGAL_REPORT_FORMAT_ENTER_AGAIN = "Illegal report format . Enter again";

	private String  _csv="CSV";
	private String  _block="block";
	private IReportHandler _reportHandler;
	private CEmployeeCSVPrinter _CSVPrinter;
	private CEmployeeBlockPrinter _BlockPrinter;
	
	public CReportInputReader(CEmployeeHandler employeeHandler) {
		this._reportHandler = new CReportHandler(employeeHandler);
		this._CSVPrinter = new CEmployeeCSVPrinter();
		this._BlockPrinter = new CEmployeeBlockPrinter();
	}

	public void readInformationFromCommandLine(){
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String tReportRecord = null;
		
		String argument = null;
		String format = null;
		String recordType = null;
		double amount = 0;
		Collection<IEmployee> EmployeeSuitbleForReport = null;
		Collection<IEmployee> CSpecialistSuitbleForReport = null;
		

		System.out.println("Enter report commands");
		
		try
		 {
			tReportRecord= br.readLine();
		 }
		catch(IOException e){
			malformedReportInput();
		}
		
		
		while(!tReportRecord.equals("STOP")){
			try{
			// report-type  parsing
			recordType = _parser(tReportRecord);
			
			//argument parsing
			argument = _parser((tReportRecord.substring(recordType.length()+1)).trim());
			
			//format parsing	
			format= _parser((tReportRecord.substring(recordType.length()+1+argument.length())).trim());
			if ( !(format.equals( _csv) | format.equals( _block) ) )
				format=readFormatAgain();
			}
			

			
			
			catch(StringIndexOutOfBoundsException e){
				malformedReportInput();
				
			}
				
			switch (reportType(recordType)){
				case 0://Expenses    			
					
					amount = ParseAmountFromString(argument);	
					EmployeeSuitbleForReport = this._reportHandler.getExpenses(amount);
					
					if (format.equals(_csv)) printEmployeeCollectionInCSV(EmployeeSuitbleForReport);

					else
						if (format.equals(_block)) printEmployeeCollectionInBlock(EmployeeSuitbleForReport);
						else malformedReportInput();
					
					break;
				case 1://Equipment
					
					CSpecialistSuitbleForReport = this._reportHandler.getEquipment(argument);
										
					if (format.equals(_csv)) printEmployeeCollectionInCSV(CSpecialistSuitbleForReport);
					
					else 
						if (format.equals(_block)) printEmployeeCollectionInBlock(CSpecialistSuitbleForReport);
						else malformedReportInput();
					
					break;

				default:
					malformedReportInput();
			}
				
			try
			 {
				tReportRecord= br.readLine();
			 }
			catch(IOException e){
				malformedReportInput();
			}
			
			

			
			
		}
	}
	
	
	private String readFormatAgain() {
		
		System.out.println(ILLEGAL_REPORT_FORMAT_ENTER_AGAIN);
	
		
		String tFormat=null;	
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		try
		 {
			tFormat= br.readLine();
		 }
		catch(IOException e){
			readFormatAgain();
		}
		
		if ( !(tFormat.equals( _csv) | tFormat.equals( _block) ) )
			tFormat=readFormatAgain();

		return tFormat;
		
	}

	private double ParseAmountFromString(String argument) {
		double amount=0;
		
		try{
			amount = Double.parseDouble(argument);
		}
		catch (NumberFormatException e){			
				
			return ParseAmountFromString( ReadAmountAgain() );

		}
		return amount;
	}

	private String  ReadAmountAgain() {
		String tAmount=null;		
		
		System.out.println(ILLEGAL_EXPENSE_AMOUNT_ENTER_AGAIN);
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		try
		 {
			tAmount= br.readLine();
		 }
		catch(IOException e){
			tAmount=ReadAmountAgain();
		}
		
		return tAmount;
		
	}

	private int reportType(String record){
		int tAnswer = -1;
		String tTrimmedRecord = record.trim();
		
		if (tTrimmedRecord.startsWith("spend")) return 0;
		if (tTrimmedRecord.startsWith("uses")) return 1;
		
	
		return tAnswer;
	}
	
	
	private String _parser(String record){
		
		String tTrimmedRecord = record.trim();
		int tIndexOfSeperator = tTrimmedRecord.indexOf(" ");
		String tAnswer;
		
		if (tIndexOfSeperator == -1)
			tAnswer = tTrimmedRecord.substring(0);
		else
			tAnswer = tTrimmedRecord.substring(0,tIndexOfSeperator);
		
		return tAnswer;
	}
	
	
	
	private void malformedReportInput(){
		System.out.println("Malformed report inserted");
	}
	
	
	
	private void printEmployeeInCSV(IEmployee employee){
		
		int tEmployeeCode = Integer.parseInt(employee.getEmployeeCode());
		
		switch(tEmployeeCode){
			case 0:
				this._CSVPrinter.printRegularEmployee(employee);
				break;
			
			case 1:
				this._CSVPrinter.printManager(employee);
				break;
				
			case 2:
				this._CSVPrinter.printSpecialist(employee);
				break;
		}
		
	}
	
	private void printEmployeeInBlock(IEmployee employee){
		
		int tEmployeeCode = Integer.parseInt(employee.getEmployeeCode());
		
		switch(tEmployeeCode){
			case 0:
				this._BlockPrinter.printRegularEmployee(employee);
				break;
			
			case 1:
				this._BlockPrinter.printManager(employee);
				break;
				
			case 2:
				this._BlockPrinter.printSpecialist(employee);
				break;
		}
		
	}
	
	
	private void printEmployeeCollectionInCSV(Collection<IEmployee> EmployeeSuitbleForReport){
	
		IEmployee tmpIteratorEmployee = null;
		for(Iterator<IEmployee> iterator = EmployeeSuitbleForReport.iterator(); iterator.hasNext();){
			
			tmpIteratorEmployee = iterator.next();
			
			printEmployeeInCSV(tmpIteratorEmployee);
		}
	}
	
	private void printEmployeeCollectionInBlock(Collection<IEmployee> EmployeeSuitbleForReport){
		
		IEmployee tmpIteratorEmployee = null;
		for(Iterator<IEmployee> iterator = EmployeeSuitbleForReport.iterator(); iterator.hasNext();){
			
			tmpIteratorEmployee = iterator.next();
			
			printEmployeeInBlock(tmpIteratorEmployee);
		}
	}
	

}



